<?php

namespace app\common\service\queue;

use think\facade\Db;
use app\common\model\PushTask as PushTaskModel;
use app\common\model\PushQueue as PushQueueModel;
use app\common\model\User as UserModel;
use app\common\model\UserInfo as UserInfoModel;
use app\common\model\UserWx as UserWxModel;
use XYCms\Push;

class PushTask
{
    public $isExecuteing = false;
    public function push_handle()
    {
        if ($this->isExecuteing) return;
        $this->isExecuteing = true;
        $PushTaskModel = PushTaskModel::where(['status' => 0])->field('id,uid,client,event,status,data')
            ->withAttr('client', function ($v, $data) {
                return $v ? explode(',', $v) : '';
            })
            ->withAttr('data', function ($v, $data) {
                return json_decode($v, true);
            })->find();
        if ($PushTaskModel) {
            $PushTaskModel->status = 1;
            $PushTaskModel->save();
            $push = new Push($PushTaskModel->toArray());
            $push->init();
        }
        $this->isExecuteing = false;
    }
    public function push_queue_handle()
    {
        Db::startTrans();
        $Find = PushQueueModel::where(['status' => 0])->lock(true)->order('id asc')->find();
        if (!$Find) return Db::commit();
        $where = [];
        if ($Find->next_id) {
            $where[] = ['id', '>', $Find->next_id];
        }
        $UserData = null;
        switch ($Find->crowd) {
            case 'all':
                $UserData = UserModel::where(['status' => 1])->where($where)->limit(5)->field('id as uid,id as next_id')->order('id asc')->select()->toArray();
                break;
            case 'company':
                $UserData = UserInfoModel::where(['role_type' => 1])->where($where)->limit(5)->field('uid,id as next_id')->order('id asc')->select()->toArray();
                break;
            case 'personal':
                $UserData = UserInfoModel::where(['role_type' => 0])->where($where)->limit(5)->field('uid,id as next_id')->order('id asc')->select()->toArray();
                break;
            case 'mp':
                $UserData = UserWxModel::where(['subscribe' => 1])->whereNotNull('wx_openid')->where($where)->limit(5)->field('wx_openid,uid,id as next_id')->order('id asc')->select()->toArray();
                break;
            case 'mobile':
                $UserData = UserModel::where(['status' => 1])->whereNotNull('mobile')->where($where)->limit(5)->field('id as uid,id as next_id')->order('id asc')->select()->toArray();
                break;
            case 'email':
                $UserData = UserModel::where(['status' => 1])->whereNotNull('email')->where($where)->limit(5)->field('id as uid,id as next_id')->order('id asc')->select()->toArray();
                break;
        }
        $push_sum = count($UserData);
        if ($push_sum) {
            $TaskList = [];
            $msgData = json_encode(['title' => $Find->title, 'desc' => $Find->desc, 'content' => $Find->content], JSON_UNESCAPED_UNICODE);
            $next_id = 0;
            foreach ($UserData as $k => $v) {
                $uid = null;
                if (!empty($v['uid']))
                    $uid = $v['uid'];
                $wx_openid = null;
                if (!empty($v['wx_openid']))
                    $wx_openid = $v['wx_openid'];
                $is_add = ($uid || $wx_openid);
                if ($Find->crowd === 'mp')
                    $is_add = $wx_openid;
                if ($is_add) {
                    $TaskList[] = [
                        'uid'       =>  $uid,
                        'wx_openid' =>  $wx_openid,
                        'client'    =>  $Find->client,
                        'event'     =>  'sendSiteMsg',
                        'data'      =>  $msgData
                    ];
                }
                $next_id = $v['next_id'];
            }
            $PushTaskModel = new PushTaskModel;
            $Find->next_id = $next_id;
            $Find->push_sum = Db::raw('push_sum+' . $push_sum);
        } else {
            $Find->status = 1;
        }
        try {
            $Find->save();
            if (!empty($TaskList)) $PushTaskModel->saveAll($TaskList);
            // 提交事务
            Db::commit();
        } catch (\Exception $e) {
            // 回滚事务
            Db::rollback();
        }
    }
}
